package com.maas.util.mybatis.jpa.littlenb.support.template.select;

import com.littlenb.mybatisjpa.support.template.SqlTemplate;
import com.littlenb.mybatisjpa.util.PersistentUtil;
import com.maas.util.mybatis.jpa.littlenb.common.JpaTools;
import com.maas.util.mybatis.jpa.littlenb.conditions.plus.core.enums.SqlMethod;
import com.maas.util.mybatis.jpa.littlenb.conditions.plus.core.metadata.TableInfo;
import com.maas.util.mybatis.jpa.littlenb.conditions.plus.core.metadata.TableInfoHelper;
import com.maas.util.mybatis.jpa.littlenb.conditions.plus.core.toolkit.Constants;
import com.maas.util.mybatis.jpa.littlenb.conditions.plus.core.toolkit.sql.SqlScriptUtils;
import org.apache.ibatis.jdbc.SQL;

import javax.persistence.Column;
import java.lang.reflect.Field;


import static com.maas.util.mybatis.jpa.littlenb.conditions.plus.core.toolkit.Constants.*;

/**
 * <p>
 *  模拟 mybatis plus 的 queryWrapper
 * SelectWrapperSqlTemplate
 * </p>
 *
 * @author zxm
 * @date 2021/07/09 14:17
 * @since 2021/07/09 14:17
 */
public class SelectWrapperSqlTemplate  implements SqlTemplate {
    public static final SelectWrapperSqlTemplate INSTANCE = new SelectWrapperSqlTemplate();

    /**
     * 查询 的字段
     */
    public  String selectParm = "";


    public static boolean selectable(Field field) {
        if (!PersistentUtil.isPersistentField(field) || PersistentUtil.isAssociationField(field)) {
            return false;
        }

        if (field.isAnnotationPresent(Column.class)) {
            Column column = field.getAnnotation(Column.class);
            return column.insertable();
        }

        return true;
    }

    @Override
    public String parseSQL(final Class<?> type) {
        /**
         * 模仿 mybati-plus 的 injectMappedStatement
         */

        //查询字段, 如 ${ew.sqlSelect}
        String sqlSelectColumns =sqlSelectColumns(type);
        String sql = new SQL() {
            {
                SELECT(sqlSelectColumns);
                FROM(PersistentUtil.getTableName(type) +" p");
            }
        }.toString();


        //  where 后面的sql片段, 如 ${ew.customSqlSegment}
         sql =sql+sqlWhereEntityWrapper(true,type)+sqlComment();
        return sql;


    }


    /**
     * ${ew.sqlSelect}
     * @param type
     * @return
     */
    public  String sqlSelectColumns(final Class<?> type) {
        String columns ="";
        if(JpaTools.isNotEmpty(selectParm)){
            columns =selectParm;
        }else {
            for (Field field : PersistentUtil.getPersistentFields(type)) {
                if (selectable(field)) {
//            SET(PersistentUtil.getColumnName(field) + " = " + ColumnMetaResolver
//                .resolveSqlPlaceholder(field))
                    columns += "p." + PersistentUtil.getColumnName(field)+",";
                }
            }
            columns =JpaTools.cutOffLastStr(columns,",");
        }

        //  ${ew.sqlSelect}  || 全部字段
        String sqlSelectColumns = SqlScriptUtils.convertChoose(String.format("%s != null and %s != null", Constants.WRAPPER, Q_WRAPPER_SQL_SELECT),
                SqlScriptUtils.unSafeParam(Q_WRAPPER_SQL_SELECT), columns);

        return sqlSelectColumns;
    }

    /**
     * ${ew.customSqlSegment}
     * where 后面的sql 片段
     * @param newLine
     * @param table
     * @return
     */
    public String sqlWhereEntityWrapper(boolean newLine,final Class<?> type) {
        //  ${ew.customSqlSegment}
        String customSqlSegment =SqlScriptUtils.convertChoose(String.format("%s != null and %s != null", Constants.WRAPPER, WRAPPER_DOT+"custom"+"SqlSegment"),
                SqlScriptUtils.unSafeParam(WRAPPER_DOT+"custom"+"SqlSegment"), "");
        return customSqlSegment;
    }

    /**
     * SQL 注释
     *
     * @return sql
     */
    protected String sqlComment() {
        return SqlScriptUtils.convertChoose(String.format("%s != null and %s != null", WRAPPER, Q_WRAPPER_SQL_COMMENT),
                SqlScriptUtils.unSafeParam(Q_WRAPPER_SQL_COMMENT), EMPTY);
    }

    /**
     * SQL 注释
     *
     * @return sql
     */
    protected String sqlFirst() {
        return SqlScriptUtils.convertChoose(String.format("%s != null and %s != null", WRAPPER, Q_WRAPPER_SQL_FIRST),
                SqlScriptUtils.unSafeParam(Q_WRAPPER_SQL_FIRST), EMPTY);
    }
}
